﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using GalaSoft.MvvmLight.Messaging;
using JiveMessenger.Log;
using JiveMessenger.User;
using JiveMessenger.Utilities;
using JmShared;
using System;
using System.ComponentModel;
using System.Security;
using System.Threading.Tasks;

namespace JiveMessenger.ViewModels
{

    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class ViewModelResetPasswordPage : ViewModelBaseEx
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private IClient _currentClient;
        public RelayCommand ResetPasswordCommand { get; set; }
        public RelayCommand<string> PasswordChangedCommand { get; set; }
        public RelayCommand<string> RepeatPasswordChangedCommand { get; set; }

        private bool _sentVerificationSuccess;
        public bool SendVerificationSuccess
        {
            get { return _sentVerificationSuccess; }
            set
            {
                if (_sentVerificationSuccess != value)
                {
                    Set(() => SendVerificationSuccess, ref _sentVerificationSuccess, value);
                }
            }
        }
        private string _verificationCode;
        public string VerificationCode
        {
            get { return _verificationCode; }
            set
            {
                if (_verificationCode != value)
                {
                    Set(() => VerificationCode, ref _verificationCode, value);
                }
            }
        }
        private string _username;
        public string Username
        {
            get { return _username; }
            set
            {
                if (_username != value)
                {
                    Set(() => Username, ref _username, value);
                }
            }
        }
        private string _usernameStatusText;
        public string UsernameStatusText
        {
            get { return _usernameStatusText; }
            set
            {
                if (_usernameStatusText != value)
                {
                    Set(() => UsernameStatusText, ref _usernameStatusText, value);
                }
            }
        }
        private string _nextButtonText;
        public string NextButtonText
        {
            get { return _nextButtonText; }
            set
            {
                if (_nextButtonText != value)
                {
                    Set(() => NextButtonText, ref _nextButtonText, value);
                }
            }
        }

        private bool _isNextButtonEnabled;
        public bool IsNextButtonEnabled
        {
            get
            {
                if (SendVerificationSuccess)
                    return _isNextButtonEnabled && (Username != null && Username.Length > 0) && (IsPasswordOK && IsRepeatPasswordOK);
                else
                    return _isNextButtonEnabled && (Username != null && Username.Length > 0);
            }
            set
            {
                if (_isNextButtonEnabled != value)
                {
                    Set(() => IsNextButtonEnabled, ref _isNextButtonEnabled, value);
                }
            }
        }

        private bool _isCancelButtonEnabled;
        public bool IsCancelButtonEnabled
        {
            get { return _isCancelButtonEnabled; }
            set
            {
                if (_isCancelButtonEnabled != value)
                {
                    Set(() => IsCancelButtonEnabled, ref _isCancelButtonEnabled, value);
                }
            }
        }

        private string _password;
        public string Password
        {
            get { return _password; }
            set
            {
                if (_password != value)
                {
                    Set(() => Password, ref _password, value);
                }
            }
        }
        private string _repeatPassword;
        public string RepeatPassword
        {
            get { return _repeatPassword; }
            set
            {
                if (_repeatPassword != value)
                {
                    Set(() => RepeatPassword, ref _repeatPassword, value);
                }
            }
        }

        private bool _isRepeatPasswordOK;
        public bool IsRepeatPasswordOK
        {
            get { return _isRepeatPasswordOK; }
            set
            {
                if (_isRepeatPasswordOK != value)
                {
                    Set(() => IsRepeatPasswordOK, ref _isRepeatPasswordOK, value);
                }
            }
        }

        private string _sendVerificationStatusText;
        public string SendVerificationStatusText
        {
            get { return _sendVerificationStatusText; }
            set
            {
                if (_sendVerificationStatusText != value)
                {
                    Set(() => SendVerificationStatusText, ref _sendVerificationStatusText, value);
                }
            }
        }


        private bool _isPasswordOK;
        public bool IsPasswordOK
        {
            get { return _isPasswordOK; }
            set
            {
                if (_isPasswordOK != value)
                {
                    Set(() => IsPasswordOK, ref _isPasswordOK, value);
                }
            }
        }
        private string _passwordStatusText;
        public string PasswordStatusText
        {
            get { return _passwordStatusText; }
            set
            {
                if (_passwordStatusText != value)
                {
                    Set(() => PasswordStatusText, ref _passwordStatusText, value);
                }
            }
        }
        private string _repeatPasswordStatusText;
        public string RepeatPasswordStatusText
        {
            get { return _repeatPasswordStatusText; }
            set
            {
                if (_repeatPasswordStatusText != value)
                {
                    Set(() => RepeatPasswordStatusText, ref _repeatPasswordStatusText, value);
                }
            }
        }

        private bool _changePwSuccess;
        public bool ChangePwSuccess
        {
            get { return _changePwSuccess; }
            set
            {
                if (_changePwSuccess != value)
                {
                    Set(() => ChangePwSuccess, ref _changePwSuccess, value);
                }
            }
        }


        /// <summary>
        /// Initializes a new instance of the ViewModelResetPassword class.
        /// </summary>
        public ViewModelResetPasswordPage(IClient client)
        {
            _currentClient = client;

            IsCancelButtonEnabled = true;
            NextButtonText = "Next";
            IsNextButtonEnabled = true;
            ResetPasswordCommand = new RelayCommand(ResetPasswordCommandAction, () => IsNextButtonEnabled);
            this.PasswordChangedCommand = new RelayCommand<string>(PasswordChangedCommandAction);
            this.RepeatPasswordChangedCommand = new RelayCommand<string>(RepeatPasswordChangedCommandAction);
        }

        private void CheckPasswordEquality()
        {
            if (this.RepeatPassword == null || this.Password == null)
                return;
            if (!this.RepeatPassword.Equals(this.Password))
            {
                this.RepeatPasswordStatusText = "Passwords are not equal";
                this.IsRepeatPasswordOK = false;
            }
            else
            {
                RepeatPasswordStatusText = string.Empty;
                this.IsRepeatPasswordOK = true;
            }

        }
        private void RepeatPasswordChangedCommandAction(string pw)
        {

            this.RepeatPassword = pw;
            CheckPasswordEquality();
        }

        private void PasswordChangedCommandAction(string pw)
        {
            if (pw.Length >= 0 && pw.Length < 5)
            {
                PasswordStatusText = "Passwords must be at least 5 characters long";
                IsPasswordOK = false;
            }
            else
            {
                PasswordStatusText = string.Empty;
                IsPasswordOK = true;
            }

            this.Password = pw;
            CheckPasswordEquality();
        }

        private async void ResetPasswordCommandAction()
        {
       
            IsNextButtonEnabled = false;
          
            if (SendVerificationSuccess && ChangePwSuccess)
            {
                Messenger.Default.Send(new NotificationMessage(this, "CloseWindow"));
            }
            else if (SendVerificationSuccess)
            {
                PasswordReset pr = new PasswordReset()
                {
                    UserName = Username,
                    NewPassword = this.Password,
                    VerificationToken = this.VerificationCode
                };
                DatabaseQueryResponse response = await _currentClient.Connection.ResetPassword(pr, AppSettings.Instance.ServerSetting, StaticSettings.ServerPort);
                this.ChangePwSuccess = response.Success;
                this.SendVerificationStatusText = response.StatusText;
                if (response.Success == true)
                {
                    NextButtonText = "Done";
                    IsCancelButtonEnabled = false;
                    Logger.Info("Password successfully reset for {0}", this.Username);
                }
                else
                    Logger.Warn("Password reset for {0} failed", this.Username);
                IsNextButtonEnabled = true;
                this.ResetPasswordCommand.RaiseCanExecuteChanged();
            }
            else
            {
                VerifyMail vm = new VerifyMail(this.Username);
                DatabaseQueryResponse response = await _currentClient.Connection.VerifyPasswordResetEmail(vm, AppSettings.Instance.ServerSetting, StaticSettings.ServerPort);
                this.SendVerificationSuccess = response.Success;
                this.UsernameStatusText = response.StatusText;
                if (response.Success == true)
                {
                    NextButtonText = "Next";
                    IsCancelButtonEnabled = true;
                    Logger.Info("Password reset token successfully sent for {0}", this.Username);
                }
                else
                    Logger.Warn("Sending of password reset token failed for {0}", this.Username);

                IsNextButtonEnabled = true;
                this.ResetPasswordCommand.RaiseCanExecuteChanged();
            }
        }
        public override void Cleanup()
        {

            SimpleIoc.Default.Unregister<ViewModelResetPasswordPage>(VmHelper.Locator.ViewModelResetPasswordKey);
            VmHelper.Locator.ViewModelResetPasswordKey = System.Guid.NewGuid().ToString();
            base.Cleanup();
        }
    }
}